#include "xmlrpcparser.h"
#include "xmlrpcresponse.h"

#include <QtCore/QDebug>
#include <QtCore/QVariant>

namespace XmlRpc {

class XmlRpcResponsePrivate {
public:
    XmlRpcResponsePrivate()
        : error(XmlRpcResponse::NoError), errorCode(0), errorString(""), finished(false),
          value(QVariant()), rawResponse(""), methodCalled("")
    {

    }
    ~XmlRpcResponsePrivate() {}

    XmlRpcResponse::XmlRpcError error;
    int errorCode;
    QString errorString;
    bool finished;
    QVariant value;
    QString rawResponse;
    QString methodCalled;
    bool publish;
};

XmlRpcResponse::XmlRpcResponse(const QString &methodCalled, bool publish) :
    QObject(0), d(new XmlRpcResponsePrivate())
{
    d->methodCalled = methodCalled;
    d->publish = publish;
}

XmlRpcResponse::~XmlRpcResponse()
{
    delete d;
}

XmlRpcResponse::XmlRpcError XmlRpcResponse::error() const
{
    return d->error;
}

int XmlRpcResponse::errorCode() const
{
    return d->errorCode;
}

QString XmlRpcResponse::errorString() const
{
    return d->errorString;
}

bool XmlRpcResponse::isFinished() const
{
    return d->finished;
}

QString XmlRpcResponse::methodCalled() const
{
    return d->methodCalled;
}

QVariant XmlRpcResponse::returnValue() const
{
    return d->value;
}

QString XmlRpcResponse::rawResponse() const
{
    return d->rawResponse;
}

void XmlRpcResponse::setRawResponse(const QString &text)
{
    d->rawResponse = text;
}

void XmlRpcResponse::setError(XmlRpcError error, int errorCode, const QString &errorString)
{
    if (!d->finished) {
        d->error = error;
        d->errorCode = errorCode;
        d->errorString = errorString;
    }
}

void XmlRpcResponse::setReturnValue(const QVariant &value)
{
    if (!d->finished)
        d->value = value;
}

void XmlRpcResponse::parseResponse(const QString &content)
{
    // Don't fiddle with the contents if we are already done
    if (d->finished)
        return;
    setRawResponse(content);
    XmlRpcParser parser;
    XmlRpcParserContents contents = parser.parseRpcResponse(content);
    if (contents.isFault()) {
        setError(RpcFaultError, contents.faultCode(), contents.faultString());
        setReturnValue(QVariant());
        return;
    }
    setReturnValue(contents.params());
}

bool XmlRpcResponse::publish() const
{
    return d->publish;
}

void XmlRpcResponse::done()
{
    d->finished = true;
    emit finished(this);
}

} // namespace XmlRpc
